{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## stacking 模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "为什么需要模型融合：多个学习器进行结合，常可获得比单一学习器显著优越的泛化性能。 --《机器学习 周志华》"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "stacking模型融合策略：我们做两层，第一层模型是lgb和xgb，第二层模型是lr(逻辑回归)\n",
    "第一层模型的作用：将数据训练并预测，并将训练结果和预测结果作为特征\n",
    "第二层模型的作用：将第一层的两个模型的训练结果和预测结果作为训练集和预测集，对数据进行训练和预测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x273961d6c88>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA20AAAH5CAYAAAASmta2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAgAElEQVR4nOzdeVxUVf8H8M+pENQEWVQMtGRIEzdUcEtKpxTSxzTLwL2SXPuVWoKPVtrzpAmVtooWVioq2uJuoI9gipqKCy64ARriyiaYyqLd3x/D3JlhZticYQb4vF8vXs4999xzzzAI851zzvcISZJARERERERE1ukhS3eAiIiIiIiIjGPQRkREREREZMUYtBEREREREVkxBm1ERERERERWjEEbERERERGRFWPQRkREREREZMXMErQJIQKEEGeFEClCiJnmuAcREREREVFdIEy9T5sQ4mEA5wD0A5AB4BCA4ZIkJZv0RkRERERERHWAOUbaugFIkSQpTZKkIgDRAAab4T5ERERERES13iNmaNMNwCWt4wwA3UtXEkKMBzAeABo2bNj1qaeeMkNXiIiIiIiIrN/hw4ezJElqYuicOYI2YaBMbw6mJEnfAfgOAHx8fKTExEQzdIWIiIiIiMj6CSH+MnbOHNMjMwC00Dp2B3DFDPchIiIiIiKq9cwRtB0C8KQQopUQoh6AIACbzHAfIiIiIiKiWs/k0yMlSbonhHgLQCyAhwH8IEnSKVPfh4iIiIiIqC4wx5o2SJK0DcA2c7RNRERERERUl5hlc20iIiIiIiIyDQZtREREREREVoxBGxERERERkRVj0EZERERERGTFGLQRERERERFZMQZtREREREREVoxBGxERERERkRVj0EZERERERGTFGLQRERERERFZMQZtREREREREVoxBGxERERERkRVj0EZERERERGTFGLQRERERERFZMQZtREREREREVoxBGxERERERkRVj0EZERERERGTFGLQRERERERFZMQZtREREREREVoxBGxERERERkRVj0EZERERERGTFGLQRERERERFZMQZtREREREREVoxBGxERERERkRVj0EZERERERGTFGLQRERERERFZMQZtREREREREVoxBGxERERERkRVj0EZERERERGTFGLQRERERERFZMQZtREREREREVoxBGxERERERkRVj0EZERERERGTFGLQRERERERFZMQZtREREREREVoxBGxERERERkRVj0EZERERERGTFGLQRERERERFZMQZtREREREREVoxBGxERERERkRVj0EZERERERGTFGLQRERERERFZMQZtREREREREVoxBGxERERERkRVj0EZERERERGTFyg3ahBA/CCFuCCFOapU5CSF2CCHOl/zrWFIuhBBfCSFShBDHhRBdzNl5IiIiIiKi2q4iI20/AQgoVTYTwE5Jkp4EsLPkGABeAPBkydd4ABGm6SYREREREVHdVG7QJknSbgA5pYoHA1he8ng5gCFa5SsklT8BNBZCNDdVZ4mIiIiIiOqaqq5payZJ0lUAKPm3aUm5G4BLWvUySsr0CCHGCyEShRCJmZmZVewGERERERFR7WbqRCTCQJlkqKIkSd9JkuQjSZJPkyZNTNwNIiIiIiKi2qGqQdt19bTHkn9vlJRnAGihVc8dwJWqd4+IiIiIiKhuq2rQtgnA2JLHYwFs1CofU5JFsgeAPPU0SiIiIiIiIqq8R8qrIIRYA6APABchRAaAOQAWAFgnhBgHIB3AsJLq2wAMAJAC4A6A183QZyIiIiIiojqj3KBNkqThRk49Z6CuBGDKg3aKiIiIiIiIVEydiISIiIiIiIhMiEEbERERERGRFWPQRkREREREZMUYtBEREREREVkxBm1ERERERERWjEEbERERERGRFWPQRkREREREZMUYtBEREREREVkxBm1ERERERERWjEEbERERERGRFWPQRkREREREZMUYtBEREREREVkxBm1ERERERERWjEEbERERERGRFXvE0h0gXRm5hZj5a6qlu0FERDVIVLCXpbtARERmxJE2IiIiIiIiK8agjYiIiIiIyIoxaCMiIiIiIrJiDNqIiIiIiIisGBOR1BBcZE5ERDuSc7B83zVLd4OIiKoZR9qIiIiIiIisGIM2IiIiIiIiK8agjYiIiIiIyIoxaCMiIiIiIrJiDNqIiIiIiIisGIM2IiIiIiIiK8agjYiIiIiIyIoxaCMiIiIiIrJiDNqIiIiIiIisGIM2IiIiIiIiK8agrY7Lzs5GeHg4AgICIIRAQEAAJk+ejKSkJEt3jYiIiIiIADxi6Q6Q5Wzbtg0DBw7UKYuNjQUAREREQKFQYPv27fDw8LBE94iIiIiICBxpq5PS0tIghMDAgQPh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\n",
      "text/plain": [
       "<Figure size 1080x1080 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "stacking_plt = plt.imread('../doc/assets/model_fusion.png')  # 导入图片\n",
    "plt.figure(figsize=(15, 15))  # 图片大小\n",
    "plt.imshow(stacking_plt)  # 打印图片"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd  # 数据处理包\n",
    "import numpy as np  # 数据处理包\n",
    "from sklearn.metrics import roc_auc_score  # roc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "train = pd.read_csv('../data/train.csv')\n",
    "test = pd.read_csv('../data/train.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((100000, 300), (100000, 300))"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train.shape, test.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "train = train.fillna(-999) ### 填充特殊值\n",
    "test = test.fillna(-999)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "feats = [x for x in train.columns if x not in ['id','label']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = train['label'].values\n",
    "X = train[feats].values\n",
    "test_id = test['id'].values\n",
    "X_test = test[feats].values\n",
    "y_test  = test['label'].values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 载入五折工具及各个模型\n",
    "from sklearn.model_selection import StratifiedKFold  # 数据切分、分层五折验证包\n",
    "import lightgbm as lgb  # lgb模型 ,安装的方法是在anaconda promote里，直接pip install lightgbm 即可\n",
    "import xgboost as xgb  # xgb模型，安装的方法是在anaconda promote里，直接pip install xgboost 即可，和lightgbm一样\n",
    "# 设置skf\n",
    "data_seed = 2020\n",
    "skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=data_seed)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# lgb和xgb的参数\n",
    "lgb_params = {\n",
    "    'boosting': 'gbdt',\n",
    "    'objective': 'binary',\n",
    "    'metric': 'auc',\n",
    "    'learning_rate': 0.06,\n",
    "    'num_leaves': 31,\n",
    "    'max_depth': -1,\n",
    "    'bagging_fraction': 0.8,\n",
    "    'bagging_freq': 5,\n",
    "    'feature_fraction': 0.8,\n",
    "    'feature_fraction_seed': 300, ### 特征抽样的随机种子\n",
    "    'bagging_seed': 3, ### 数据抽样的随机种子,取10个不同的，然后对结果求平均,todo:求出10个结果，然后求平均\n",
    "    #'is_unbalance': True   #### 第一种方法：设置is_unbalance为True，表明传入的数据集是类别不平衡的\n",
    "    #'scale_pos_weight': 98145/1855###负样本数量/正样本数量 -> scale_pos_weight * 正样本 == 负样本\n",
    "}\n",
    "xgb_params = {\n",
    "    'booster': 'gbtree',  ##提升类型\n",
    "    'objective': 'binary:logistic',  ###目标函数\n",
    "    'eval_metric': 'auc',  ##评价函数\n",
    "    'eta': 0.1,  ### 学习率 ，一般0.0几\n",
    "    'max_depth': 6,  ###树最大深度\n",
    "    'min_child_weight': 1,  ###最小样本二阶梯度权重, 取值是整数\n",
    "    'subsample': 1.0,  ###训练数据采样 ,取值0.0~1.0之间\n",
    "    'colsample_bytree': 1.0,  ###训练特征采样，取值0.0~1.0之间\n",
    "    'lambda': 1,  ## l2正则，取值是整数\n",
    "    'alpha': 0,   ### l1正则，取值整数\n",
    "    'silent': 1   ### 取值1控制xgboost训练信息不输出\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "blend_train = pd.DataFrame()  # 定义df数据，以便做融合\n",
    "blend_test = pd.DataFrame()  # 定义df数据，以便做融合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "training fold:  1\n",
      "Training until validation scores don't improve for 50 rounds\n",
      "[50]\tvalid_0's auc: 0.971437\n",
      "[100]\tvalid_0's auc: 0.976224\n",
      "[150]\tvalid_0's auc: 0.977292\n",
      "[200]\tvalid_0's auc: 0.977833\n",
      "[250]\tvalid_0's auc: 0.977789\n",
      "Early stopping, best iteration is:\n",
      "[233]\tvalid_0's auc: 0.977946\n",
      "auc score:  0.9779461572822764\n",
      "training fold:  2\n",
      "Training until validation scores don't improve for 50 rounds\n",
      "[50]\tvalid_0's auc: 0.976491\n",
      "[100]\tvalid_0's auc: 0.977797\n",
      "[150]\tvalid_0's auc: 0.9778\n",
      "Early stopping, best iteration is:\n",
      "[113]\tvalid_0's auc: 0.978142\n",
      "auc score:  0.9781421102694882\n",
      "training fold:  3\n",
      "Training until validation scores don't improve for 50 rounds\n",
      "[50]\tvalid_0's auc: 0.976192\n",
      "[100]\tvalid_0's auc: 0.978029\n",
      "[150]\tvalid_0's auc: 0.979202\n",
      "[200]\tvalid_0's auc: 0.979367\n",
      "[250]\tvalid_0's auc: 0.979628\n",
      "[300]\tvalid_0's auc: 0.97977\n",
      "[350]\tvalid_0's auc: 0.979687\n",
      "Early stopping, best iteration is:\n",
      "[311]\tvalid_0's auc: 0.979878\n",
      "auc score:  0.9798779488899133\n",
      "training fold:  4\n",
      "Training until validation scores don't improve for 50 rounds\n",
      "[50]\tvalid_0's auc: 0.979365\n",
      "[100]\tvalid_0's auc: 0.981435\n",
      "[150]\tvalid_0's auc: 0.98168\n",
      "[200]\tvalid_0's auc: 0.982358\n",
      "Early stopping, best iteration is:\n",
      "[197]\tvalid_0's auc: 0.982363\n",
      "auc score:  0.9823631326057944\n",
      "training fold:  5\n",
      "Training until validation scores don't improve for 50 rounds\n",
      "[50]\tvalid_0's auc: 0.975405\n",
      "[100]\tvalid_0's auc: 0.977893\n",
      "[150]\tvalid_0's auc: 0.978275\n",
      "[200]\tvalid_0's auc: 0.978126\n",
      "Early stopping, best iteration is:\n",
      "[153]\tvalid_0's auc: 0.978313\n",
      "auc score:  0.9783132086731785\n"
     ]
    }
   ],
   "source": [
    "# 训练lgb，用作第一层模型中的其中一个\n",
    "test_pred_lgb = 0  # 预测结果存放对象\n",
    "cv_score_lgb = []  # 存放每次auc的对象\n",
    "train_feats = np.zeros(X.shape[0])  # 整体训练的样本数量\n",
    "for idx, (train_idx, test_idx) in enumerate(skf.split(X, y)):\n",
    "    print('training fold: ', idx + 1)  # 遍历的第几次\n",
    "    train_x, valid_x = X[train_idx], X[test_idx]  # 拆分成训练集和验证集\n",
    "    train_y, valid_y = y[train_idx], y[test_idx]  # 拆分成训练集和验证集\n",
    "    dtrain = lgb.Dataset(train_x, train_y, feature_name=feats)  # 组成训练集\n",
    "    dvalid = lgb.Dataset(valid_x, valid_y, feature_name=feats)  # 组成验证集\n",
    "    model = lgb.train(lgb_params, dtrain, num_boost_round=2000, valid_sets=dvalid, early_stopping_rounds=50, verbose_eval=50)  # 定义lgb模型\n",
    "\n",
    "    valid_pred = model.predict(valid_x, num_iteration=model.best_iteration)  # 当前模型最佳参数并预测，num_iteration：选择最优的lgb\n",
    "    train_feats[test_idx] = valid_pred  # 每次把验证集的结果填入，做训练的结果集，由于是5折，所以每次都是1/5的数据，把它们当作lgb训练集特征\n",
    "    auc_score = roc_auc_score(valid_y, valid_pred)  # 计算auc\n",
    "    print('auc score: ', auc_score)\n",
    "    cv_score_lgb.append(auc_score)  # 存放验证集auc值\n",
    "    test_pred_lgb += model.predict(X_test, num_iteration=model.best_iteration)  # 预测结果并累加，做预测的结果集，把它们当作lgb测试集当作特征"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1.69777395e-04, 7.61534609e-04, 4.87054815e-03, ...,\n",
       "       5.55546514e-02, 3.93865215e-02, 5.10414655e-01])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_feats  # 训练的结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3.62077794e-04, 6.29276400e-04, 3.35815479e-03, ...,\n",
       "       4.64100502e-01, 3.11100442e-01, 6.07412241e-01])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_pred_lgb /= 5\n",
    "test_pred_lgb  # 测试的结果，由于测试的结果是5折每次的累加，所以需要除于5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将训练结果和预测结果加入到blend数据集\n",
    "blend_train['lgb_feat'] = train_feats\n",
    "blend_test['lgb_feat'] = test_pred_lgb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "training fold:  1\n",
      "[0]\teval-auc:0.902923\n",
      "Will train until eval-auc hasn't improved in 50 rounds.\n",
      "[50]\teval-auc:0.970518\n",
      "[100]\teval-auc:0.972938\n",
      "Stopping. Best iteration:\n",
      "[73]\teval-auc:0.972938\n",
      "\n",
      "auc score:  0.9728734878354665\n",
      "training fold:  2\n",
      "[0]\teval-auc:0.890585\n",
      "Will train until eval-auc hasn't improved in 50 rounds.\n",
      "[50]\teval-auc:0.976147\n",
      "[100]\teval-auc:0.977656\n",
      "Stopping. Best iteration:\n",
      "[65]\teval-auc:0.977656\n",
      "\n",
      "auc score:  0.9775689443489396\n",
      "training fold:  3\n",
      "[0]\teval-auc:0.903571\n",
      "Will train until eval-auc hasn't improved in 50 rounds.\n",
      "[50]\teval-auc:0.975988\n",
      "[100]\teval-auc:0.976093\n",
      "Stopping. Best iteration:\n",
      "[64]\teval-auc:0.976212\n",
      "\n",
      "auc score:  0.9760364052362702\n",
      "training fold:  4\n",
      "[0]\teval-auc:0.912538\n",
      "Will train until eval-auc hasn't improved in 50 rounds.\n",
      "[50]\teval-auc:0.978535\n",
      "[100]\teval-auc:0.979904\n",
      "Stopping. Best iteration:\n",
      "[60]\teval-auc:0.980012\n",
      "\n",
      "auc score:  0.9799886959706327\n",
      "training fold:  5\n",
      "[0]\teval-auc:0.902044\n",
      "Will train until eval-auc hasn't improved in 50 rounds.\n",
      "[50]\teval-auc:0.97681\n",
      "[100]\teval-auc:0.978548\n",
      "Stopping. Best iteration:\n",
      "[67]\teval-auc:0.978586\n",
      "\n",
      "auc score:  0.9784056924411445\n"
     ]
    }
   ],
   "source": [
    "# 训练xgb，用作第一层模型中的其中一个\n",
    "test_pred_xgb = 0 # 预测结果存放对象\n",
    "cv_score_xgb = []  # 存放每次auc的对象\n",
    "train_feats_xgb = np.zeros(X.shape[0])  # 整体训练的样本数量\n",
    "for idx, (train_idx, test_idx) in enumerate(skf.split(X, y)):\n",
    "    print('training fold: ', idx + 1) # 遍历的第几次\n",
    "    train_x, valid_x = X[train_idx], X[test_idx]  # 拆分成训练集和验证集\n",
    "    train_y, valid_y = y[train_idx], y[test_idx]  # 拆分成训练集和验证集\n",
    "    dtrain = xgb.DMatrix(train_x, train_y, feature_names=feats)  # 组成训练集\n",
    "    dvalid = xgb.DMatrix(valid_x, valid_y, feature_names=feats)  # 组成验证集\n",
    "    watchlist = [(dvalid, 'eval')]\n",
    "    model = xgb.train(xgb_params, dtrain, num_boost_round=2000, evals=watchlist, early_stopping_rounds=50, verbose_eval=50)  # 定义xgb模型\n",
    "\n",
    "    valid_pred = model.predict(dvalid, ntree_limit=model.best_iteration)  # 当前模型最佳参数并预测，ntree_limit：选择最优的xgb\n",
    "    train_feats_xgb[test_idx] = valid_pred  # 每次把验证集的结果填入，做训练的结果集，由于是5折，所以每次都是1/5的数据\n",
    "    auc_score = roc_auc_score(valid_y, valid_pred)  # 计算auc\n",
    "    print('auc score: ', auc_score)\n",
    "    cv_score_xgb.append(auc_score)  # 存放验证集auc值\n",
    "    dtest = xgb.DMatrix(X_test,feature_names=feats)  ##同时指定特征名字\n",
    "    test_pred_xgb += model.predict(dtest, ntree_limit=model.best_iteration)  # 预测结果并累加，做预测的结果集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.00127854, 0.00197552, 0.01527219, ..., 0.06836488, 0.10070858,\n",
       "       0.64704806])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_feats_xgb  # 训练的结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.00025571, 0.0003951 , 0.00305444, ..., 0.01367298, 0.02014172,\n",
       "       0.12940961])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_feats_xgb /= 5  # 测试的结果，由于测试的结果是5折每次的累加，所以需要除于5\n",
    "train_feats_xgb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将训练结果和预测结果加入到blend数据集\n",
    "blend_train['xgb_feat'] = train_feats_xgb\n",
    "blend_test['xgb_feat'] = test_pred_xgb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>lgb_feat</th>\n",
       "      <th>xgb_feat</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.000170</td>\n",
       "      <td>0.000256</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.000762</td>\n",
       "      <td>0.000395</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.004871</td>\n",
       "      <td>0.003054</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.002038</td>\n",
       "      <td>0.001449</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.000674</td>\n",
       "      <td>0.000797</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   lgb_feat  xgb_feat\n",
       "0  0.000170  0.000256\n",
       "1  0.000762  0.000395\n",
       "2  0.004871  0.003054\n",
       "3  0.002038  0.001449\n",
       "4  0.000674  0.000797"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "blend_train.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>lgb_feat</th>\n",
       "      <th>xgb_feat</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.000362</td>\n",
       "      <td>0.008366</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.000629</td>\n",
       "      <td>0.008058</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.003358</td>\n",
       "      <td>0.064686</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.004139</td>\n",
       "      <td>0.044280</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.000489</td>\n",
       "      <td>0.018679</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   lgb_feat  xgb_feat\n",
       "0  0.000362  0.008366\n",
       "1  0.000629  0.008058\n",
       "2  0.003358  0.064686\n",
       "3  0.004139  0.044280\n",
       "4  0.000489  0.018679"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "blend_test.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LogisticRegression  # 载入lr模型，这里lr模型用作第二层模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "lr_model = LogisticRegression()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\lib\\site-packages\\sklearn\\linear_model\\logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n",
      "  FutureWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
       "                   intercept_scaling=1, l1_ratio=None, max_iter=100,\n",
       "                   multi_class='warn', n_jobs=None, penalty='l2',\n",
       "                   random_state=None, solver='warn', tol=0.0001, verbose=0,\n",
       "                   warm_start=False)"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lr_model.fit(blend_train.values, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 7.63761109, 10.70603716]])"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lr_model.coef_  # 特征权重"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_pred_lr = lr_model.predict_proba(blend_test.values)[:,1]  # 第二层模型预测结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_leaderboard_score(test_df,prediction):\n",
    "    \"\"\"\n",
    "    定义评分函数\n",
    "    test_df: 测试集\n",
    "    prediction: 预测结果\n",
    "    reture: 输出结果分数\n",
    "    \"\"\"\n",
    "    label = test_df['label'].values  # 拿出真实样本\n",
    "    assert len(prediction) == len(label)  # 断言其长度相等\n",
    "    print('stacking auc score: ', roc_auc_score(label, prediction))  # 计算评分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Online auc score:  0.9941125561099089\n"
     ]
    }
   ],
   "source": [
    "get_leaderboard_score(test,test_pred_lr)  # stacking模型的分数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Online auc score:  0.9985280429047785\n"
     ]
    }
   ],
   "source": [
    "get_leaderboard_score(test,test_pred_lgb)  # lgb模型的分数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Online auc score:  0.9902076703441838\n"
     ]
    }
   ],
   "source": [
    "get_leaderboard_score(test,test_pred_xgb)  # xgb模型的分数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0.9793285115441301, 0.0016649382928107428)"
      ]
     },
     "execution_count": 79,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.mean(cv_score_lgb), np.std(cv_score_lgb) # lgb验证集评分"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 专家投票"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [],
   "source": [
    "blend_result = 0.5 * test_pred_lgb + 0.5 * test_pred_xgb  # 模型平均加权"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Online auc score:  0.9946536225418163\n"
     ]
    }
   ],
   "source": [
    "get_leaderboard_score(test,blend_result)  # 加权模型分数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
